#pragma once


#include "rapidxml/rapidxml.hpp"
#include "rapidxml/rapidxml_print.hpp"
#include "rapidxml/rapidxml_utils.hpp"
#include "cpputil.h"

typedef rapidxml::xml_node<TCHAR> _xmlNode;
typedef rapidxml::xml_document<TCHAR> _xmlDoc;
typedef rapidxml::xml_attribute<TCHAR> _xmlAttribute;
typedef rapidxml::file<TCHAR> _xmlFileContent;

class XMLNode
{
public:
	XMLNode(_xmlNode* pnode):mpNode(pnode){}

	TCHAR* getNodeType()const;

	void addChild(const XMLNode& elm);
	XMLNode getParent()const;

	XMLNode firstChildElement(const TCHAR* name=0)const;
	XMLNode nextSibElement(const TCHAR* name=0)const;

	XMLNode firstChildNode(const TCHAR* name=0)const;
	XMLNode nextSibNode(const TCHAR* name=0)const;

	bool isElement()const;
	bool isComment()const;
	
	bool removeChildNode(const XMLNode& node);
	

	
	const TCHAR* getAttribute( const TCHAR* sAttri )const;
	XMLNode& setAttribute(const TCHAR*sAttri, const TCHAR* val);
	bool hasAttribute(const TCHAR*sAttri)const;
	XMLNode& removeAttribute(const TCHAR*sAttri);


	

	XMLNode createChildElement(const TCHAR* sType);

	//some common used attribute
	int GetID()const;
	void SetID(int id);
	//text
	const TCHAR* getText()const;
	void setText(const TCHAR* s); 



public:

	operator bool()const{ return mpNode!=NULL; } 
	static TCHAR aID[];
	static TCHAR aName[];

public:
	_xmlNode* mpNode;
	static TCHAR sBlank[] ;
};

//////////////////////////////////////////////////////////////////////////
class XMLDoc  : public cpputil::noncopyable
{
public:
	XMLDoc();	
	~XMLDoc(); 
	void Save(const TCHAR* fileName);
	void Read(const TCHAR* fileName);
	void Print();


	XMLNode newElement(const TCHAR* sName);
	void addElement(const XMLNode& elm);
protected:
	_xmlDoc * mpDoc;
	_xmlFileContent* mpReadFile;
};

#define  NODE_CONVERSION(D,P)  public:\
									D(const XMLNode& node):P(node){  }  \
									static TCHAR sType[];

#define NODE_TYPEIMPL(T, S)  TCHAR T::sType[] = _T(S);

